using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using Universum.Infrastructure.Persistence;
using Universum.Infrastructure.Persistence.Queries;
using Universum.Model.Domain;
using Universum.Infrastructure.Utils;
using System.Security.Principal;
using Universum.Infrastructure.Configuration;
using Universum.Model.Services;

namespace Universum.Controllers
{
	[HandleError]
    public class ArticleController : UniversumController
    {
		
		private readonly string[]  _whitelist;

		public IFriendlyUrlService SlugService { get; set; }
		IRepository Repository;
		public ArticleController(IRepository repository, IPrincipal currentUser, IFriendlyUrlService slugService):base(currentUser)
		{
			Repository = repository;
			SlugService = slugService;
			_whitelist = new string[]{
					MemberUtil<Article>.MemberName(a=>a.Slug),
					MemberUtil<Article>.MemberName(a=>a.Title),
					MemberUtil<Article>.MemberName(a=>a.Text),
					MemberUtil<Article>.MemberName(a=>a.Publish),
					MemberUtil<Article>.MemberName(a=>a.Created)
				};
		}
		private Article GetArticleBasedOnItsSlugAndCurrentUser(string slug)
		{
			string username = RouteData.Values[ConstantIdentifiers.ROUTE_USERNAME_KEY].ToString();
			Article articleByUsernameAndSlug;
			if(username.IsNullOrEmpty())
				articleByUsernameAndSlug = Repository.Query(
				new ArticleByUsernameAndSlug(CurrentUser.Identity.Name,
					slug)).SingleOrDefault();
			else
				articleByUsernameAndSlug = Repository.Query(
				new ArticleByUsernameAndSlug(username,
					slug)).SingleOrDefault();
			return articleByUsernameAndSlug;
		}
		private Article GetArticleBasedOnItsSlug(string id)
		{
			
			var articleFromSlug = Repository.Query(new ArticleBySlug(id)).SingleOrDefault();
				//articleList.First(article => article.Slug.Equals(id));
			return articleFromSlug;
		}
        //
        // GET: /Article/
		//[Authorize()]
        public ActionResult Index()
        {
			string username = RouteData.Values.ContainsKey(ConstantIdentifiers.ROUTE_USERNAME_KEY)?
				RouteData.Values[ConstantIdentifiers.ROUTE_USERNAME_KEY].ToString() : null;
			if (username.IsNullOrEmpty())
				this.ViewData.Model = Repository.Query<Article>(new ArticleByUsername(CurrentUser.Identity.Name)).ToList();
			else
				this.ViewData.Model = Repository.Query(
					new ArticleByUsername(username)).ToList();

            return View();
        }

        //
        // GET: /Article/Details/5
		//[Authorize()]
		//[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Details(string id)
        {
			var articleFromSlug = GetArticleBasedOnItsSlugAndCurrentUser(id);
			ViewData.Model = articleFromSlug;
            return View();
        }

		

        //
        // GET: /Article/CreateFile
		[Authorize()]
        public ActionResult Create()
        {
            return View();
        } 

        //
        // POST: /Article/CreateFile
		[Authorize()]
        [AcceptVerbs(HttpVerbs.Post)]
		[ValidateInput(false)]
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                // TODO: Add insert logic here
				var article = new Article();
				article.Username = CurrentUser.Identity.Name;
				UpdateDomain(article);
				article.Slug = SlugService.CreateSlugFrom(article.Title);
				Repository.SaveOrUpdate(article);


				return RedirectToAction<ArticleController>(
					controller => controller.Index());
            }
            catch
            {
                return View();
            }
        }

		private void UpdateDomain(Article article)
		{
			
			UpdateModel(article, _whitelist);
		}

        //
        // GET: /Article/Edit/5
		[Authorize()]
		//[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(string id)
        {
			var articleFromSlug = GetArticleBasedOnItsSlugAndCurrentUser(id);
			ViewData.Model = articleFromSlug;
            return View();
        }
		[Authorize]
		[AcceptVerbs( HttpVerbs.Post)]
		
		public ActionResult Remove(string id)
		{
			var selectArticle =
					GetArticleBasedOnItsSlugAndCurrentUser(id);
			Repository.Remove(selectArticle);
			return RedirectToAction<ArticleController>(
					controller => controller.Index());
		}

        //
        // POST: /Article/Edit/5
		[Authorize()]
        [AcceptVerbs(HttpVerbs.Post)]
		[ValidateInput(false)]
        public ActionResult Edit(string id, FormCollection collection)
        {
            try
            {
                // TODO: Add update logic here
				var selectArticle =
					GetArticleBasedOnItsSlugAndCurrentUser(id);
					//articleList.Find(article =>
					//article.Slug == collection["slug"]);
				UpdateDomain(selectArticle);

				selectArticle.Slug = SlugService.CreateSlugFrom(selectArticle.Title);
				Repository.SaveOrUpdate(selectArticle);
				return RedirectToAction<ArticleController>(
					controller => controller.Index());
            }
            catch
            {
                return View();
            }
        }
    }
}
